package cn.psvmc.cxzapi.util;

import cn.psvmc.cxzapi.config.ConfigKey;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/**
 * @Description 信审（天狼星报告）
 * @Author: YWX
 * @Date 2024/8/8 9:38
 **/
@Slf4j
public class HttpUtil {

    /**
     * @Description 请求信审接口
     * @Date 2024/8/8 10:02
     * @Author YWX
     * @Param [url, paramsMap]
     * @Return java.lang.String
     **/
    public static String invokePostWithMap(String url, Map<String, Object> paramsMap) {
        // 发送http请求这里是使用第三方库（apache.http）,
        // 也可使用自己项目封装的，注意ContentType要用application/x-www-form-urlencoded
        //log.info("请求三方接口 url: {} 参数：{}", url, JSON.toJSONString(paramsMap));
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
        }

        String result = "";
        CloseableHttpResponse response = null;
        try {
            StringEntity stringEntity = new UrlEncodedFormEntity(pairs, "UTF-8");
            stringEntity.setContentType("application/x-www-form-urlencoded");
            post.setEntity(stringEntity);

            response = httpclient.execute(post);
            result = EntityUtils.toString(response.getEntity(), "UTF-8");

            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                EntityUtils.consume(response.getEntity());
            }
            //log.info("请求三方接口 返回: {}", result);
        } catch (Exception ex) {
            if (response != null) {
                try {
                    EntityUtils.consume(response.getEntity());
                } catch (IOException e) {
                    log.error("请求三方接口失败: url: {}, 参数：{}, 原因: {}", url, JSON.toJSONString(paramsMap), e.getMessage());
                }
            }
        }
        return result;
    }

    /**
     * @Description 获取信审结果
     * @Date 2024/8/8 10:02
     * @Author YWX
     * @Param []
     * @Return java.lang.String
     **/
    public static String getRiskReport(Map<String, Object> customData) {
        String result = "";
        try {
            //Map<String, Object> customData = new TreeMap<>();

            // 测试环境公司id 正式环境需要更换正式，对接时业务人员发送的参数文档里找
            String companyId = ConfigKey.companyId;
            // 测试环境请求地址 正式环境需要更换正式，对接时业务人员发送的参数文档里找
            String url = ConfigKey.url;
            // 测试环境密钥 正式环境需要更换 对接时业务人员发送的参数文档里找
            String key = ConfigKey.aesKey;

            // 请求参数（根据文档填值），参数不固定有多少，具体请求参数和说明在对接文档里有说明
            // 请替换成真实参数
            //customData.put("name", "小九");
            //customData.put("ident_number", "410122199010093927");
            //customData.put("phone", "13140197098");
            customData.put("service", "risk_report_service");
            customData.put("mode", "JC5388e12_CL4c43be1");
            Object oss_path = customData.get("oss_path");//授权书地址：approve_files/202408080924029jtJ/cover.pdf
            //customData.put("licenseUrl", "https://shouwei.oss-cn-shanghai.aliyuncs.com/" + oss_path);
            customData.put("licenseUrl", oss_path);
            customData.put("licenseType", "1");
            // 上述参数都是需要更换的参数，根据自己的需要参考文档更换
            String bizDataRaw = JSONObject.toJSONString(customData);
            //AES加密得到的加密串
            String bizDataEncoded = AES.encrypt(bizDataRaw, key);

            // 请求接口
            Map<String, Object> data = new HashMap<>();
            // 公司id
            data.put("institution_id", companyId);
            // biz_data参数使用AES加密后得到的加密串
            data.put("biz_data", bizDataEncoded);
            //log.info("AES 加密模型是：{}", bizDataEncoded);
            //log.info("原始数据是：{}", AES.decrypt(AES.encrypt(bizDataRaw, key), key));
            //log.info("请求参数：{}", data);
            // 发送请求
            result = HttpUtil.invokePostWithMap(url, data);
        } catch (Exception e) {
            log.error("查询信申出错：{}", e.getMessage());
        }
        return result;
    }

    public static String sendPostJson(String url, Map<String, String> headerMap, String jsonString) throws Exception {
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("Accept", "application/json");

        // 设置头部信息
        for (Map.Entry<String, String> entry : headerMap.entrySet()) {
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }

        con.setDoOutput(true);
        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        // 获取响应码
        int responseCode = con.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new Exception("POST request not worked. Response Code: " + responseCode);
        }

        // 读取响应
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(con.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine = null;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();
        }
    }
}
